package cn.luyou.admin.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.luyou.admin.entity.ExamRecordDetail;
import cn.luyou.admin.entity.Question;
import cn.luyou.admin.entity.TrainingPaper;
import cn.luyou.admin.entity.TrainingPaperQuestion;
import cn.luyou.admin.mapper.TrainingPaperMapper;
import cn.luyou.admin.service.ExamRecordDetailService;
import cn.luyou.admin.service.QuestionService;
import cn.luyou.admin.service.TrainingPaperQuestionService;
import cn.luyou.admin.service.TrainingPaperService;

@Service
public class TrainingPaperServiceImpl extends ServiceImpl<TrainingPaperMapper, TrainingPaper> implements TrainingPaperService {

    @Autowired
    private QuestionService questionService;

    @Autowired
    private ExamRecordDetailService examRecordDetailService;

    @Autowired
    private TrainingPaperQuestionService trainingPaperQuestionService;

    @Override
    public IPage<TrainingPaper> getTrainingPapers(Integer pageNum, Integer pageSize, Long userId) {
        LambdaQueryWrapper<TrainingPaper> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TrainingPaper::getUserId, userId)
                .orderByDesc(TrainingPaper::getCreatedTime);
        return this.page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Transactional
    public TrainingPaper generateFromWrongQuestions(Long userId, Integer questionCount, String name) {
        // 获取用户的错题记录
        List<ExamRecordDetail> wrongQuestions = examRecordDetailService.getWrongQuestions(userId);
        if (wrongQuestions.isEmpty()) {
            throw new IllegalArgumentException("暂无错题记录");
        }

        // 随机选择指定数量的错题
        List<Long> selectedQuestionIds = randomSelectQuestions(
                wrongQuestions.stream()
                        .map(ExamRecordDetail::getQuestionId)
                        .distinct()
                        .collect(Collectors.toList()),
                questionCount
        );

        // 获取题目详情
        List<Question> questions = questionService.listByIds(selectedQuestionIds);
        
        // 创建训练试卷
        TrainingPaper paper = new TrainingPaper()
                .setPaperName(name + System.currentTimeMillis())
                .setUserId(userId)
                .setTotalScore(questions.stream().mapToInt(Question::getScore).sum())
                .setStatus(0)
                .setSourceType("WRONG_QUESTIONS");
        this.save(paper);

        // 保存试卷题目
        List<TrainingPaperQuestion> paperQuestions = questions.stream()
                .map(q -> new TrainingPaperQuestion()
                        .setPaperId(paper.getId())
                        .setQuestionId(q.getId()))
                .collect(Collectors.toList());
        trainingPaperQuestionService.saveBatch(paperQuestions);

        return paper;
    }

    @Override
    @Transactional
    public TrainingPaper generateRandomPaper(Long userId, String subject, Integer questionCount) {
        // 获取指定科目的所有题目
        List<Question> subjectQuestions = questionService.list(
                new LambdaQueryWrapper<Question>()
                        .eq(Question::getSubject, subject)
        );
        if (subjectQuestions.isEmpty()) {
            throw new IllegalArgumentException("该科目暂无题目");
        }

        // 随机选择指定数量的题目
        List<Question> selectedQuestions = randomSelectQuestions(subjectQuestions, questionCount);

        // 创建训练试卷
        TrainingPaper paper = new TrainingPaper()
                .setPaperName(subject + "随机训练-" + System.currentTimeMillis())
                .setUserId(userId)
                .setTotalScore(selectedQuestions.stream().mapToInt(Question::getScore).sum())
                .setStatus(0)
                .setSourceType("RANDOM");
        this.save(paper);

        // 保存试卷题目
        List<TrainingPaperQuestion> paperQuestions = selectedQuestions.stream()
                .map(q -> new TrainingPaperQuestion()
                        .setPaperId(paper.getId())
                        .setQuestionId(q.getId()))
                .collect(Collectors.toList());
        trainingPaperQuestionService.saveBatch(paperQuestions);

        return paper;
    }

    @Override
    public List<Question> getTrainingPaperQuestions(Long paperId) {
        // 获取试卷题目关联
        List<TrainingPaperQuestion> paperQuestions = trainingPaperQuestionService.list(
                new LambdaQueryWrapper<TrainingPaperQuestion>()
                        .eq(TrainingPaperQuestion::getPaperId, paperId)
        );

        if (paperQuestions.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取题目详情
        return questionService.listByIds(
                paperQuestions.stream()
                        .map(TrainingPaperQuestion::getQuestionId)
                        .collect(Collectors.toList())
        );
    }

    @Override
    @Transactional
    public void submitTrainingPaper(Long paperId, Map<Long, String> answers) {
        // 获取试卷信息
        TrainingPaper paper = this.getById(paperId);
        if (paper == null) {
            throw new IllegalArgumentException("训练试卷不存在");
        }
        if (paper.getStatus() == 1) {
            throw new IllegalArgumentException("该训练试卷已完成");
        }

        // 获取题目信息
        List<Question> questions = questionService.listByIds(answers.keySet());
        Map<Long, Question> questionMap = questions.stream()
                .collect(Collectors.toMap(Question::getId, q -> q));

        // 获取现有的试卷题目记录
        List<TrainingPaperQuestion> existingQuestions = trainingPaperQuestionService.list(
                new LambdaQueryWrapper<TrainingPaperQuestion>()
                        .eq(TrainingPaperQuestion::getPaperId, paperId)
        );

        // 更新答题记录
        for (TrainingPaperQuestion question : existingQuestions) {
            String userAnswer = answers.get(question.getQuestionId());
            if (userAnswer != null) {
                Question originalQuestion = questionMap.get(question.getQuestionId());
                question.setUserAnswer(userAnswer)
                        .setIsCorrect(originalQuestion.getCorrectAnswer().equals(userAnswer));
            }
        }
        
        // 批量更新
        trainingPaperQuestionService.updateBatchById(existingQuestions);

        // 更新试卷状态
        paper.setStatus(1);
        this.updateById(paper);
    }

    @Override
    public TrainingPaper getTrainingPaperDetail(Long paperId) {
        return this.getById(paperId);
    }

@Override
public Map<Long, String> getSavedAnswers(Long paperId, Long userId) {
    // 获取试卷信息
    TrainingPaper paper = this.getById(paperId);
    if (paper == null) {
        throw new IllegalArgumentException("训练试卷不存在");
    }
    if (!paper.getUserId().equals(userId)) {
        throw new IllegalArgumentException("无权查看此试卷");
    }

    // 获取已保存的答案
    List<TrainingPaperQuestion> paperQuestions = trainingPaperQuestionService.list(
            new LambdaQueryWrapper<TrainingPaperQuestion>()
                    .eq(TrainingPaperQuestion::getPaperId, paperId)
                    .isNotNull(TrainingPaperQuestion::getUserAnswer)
    );

    // 转换为Map格式返回
    return paperQuestions.stream()
            .filter(q -> q.getUserAnswer() != null)
            .collect(Collectors.toMap(
                    TrainingPaperQuestion::getQuestionId,  // key: 题目ID
                    TrainingPaperQuestion::getUserAnswer   // value: 用户答案
            ));
}

    @Override
    public List<TrainingPaperQuestion> getPaperResults(Long paperId) {
        return trainingPaperQuestionService.list(
                new LambdaQueryWrapper<TrainingPaperQuestion>()
                        .eq(TrainingPaperQuestion::getPaperId, paperId)
                        .select(
                                TrainingPaperQuestion::getQuestionId,
                                TrainingPaperQuestion::getUserAnswer,
                                TrainingPaperQuestion::getIsCorrect
                        )
        );
    }

    private <T> List<T> randomSelectQuestions(List<T> questions, int count) {
        if (count > questions.size()) {
            count = questions.size();
        }
        List<T> selectedQuestions = new ArrayList<>();
        Random random = new Random();
        Set<Integer> selectedIndices = new HashSet<>();

        while (selectedQuestions.size() < count) {
            int index = random.nextInt(questions.size());
            if (selectedIndices.add(index)) {
                selectedQuestions.add(questions.get(index));
            }
        }

        return selectedQuestions;
    }
} 